package aimis.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import aimis.domain.Role;
import aimis.dto.form.DepartmentForm;
import aimis.dto.form.RoleForm;
import aimis.dto.form.UserForm;
import aimis.exception.MyBindException;
import aimis.repo.AuthorityRepo;
import aimis.repo.DepartmentRepo;
import aimis.repo.RoleRepo;
import aimis.repo.UserRepo;


@Aspect
@Component
@RestControllerAdvice("aimis.controller")
public class AdminLimitation {
    @Autowired
    private UserRepo userRepo;
    @Autowired
    private DepartmentRepo departmentRepo;
    @Autowired
    private AuthorityRepo authorityRepo;
    @Autowired
    private RoleRepo roleRepo;
    @Value("${admin.name}")
    private String adminName;
    //    @Value("${admin.authority}")
//    private String adminAuthority;
    @Value("${admin.department}")
    private String adminDepartment;
    @Value("${admin.role}")
    private String adminRole;

    @Pointcut("execution(* aimis.controller.UserController.edit(..))")
    public void adminUserEdit() {
    }

    @Pointcut("execution(* aimis.controller.UserController.delete(..))")
    public void adminUserDelete() {
    }

    @Pointcut("execution(* aimis.controller.DepartmentController.delete(..))")
    public void adminDepartmentDelete() {
    }

    @Pointcut("execution(* aimis.controller.DepartmentController.add(..))")
    public void adminDepartmentAdd() {
    }

    @Pointcut("execution(* aimis.controller.DepartmentController.edit(..))")
    public void adminDepartmentEdit() {
    }

    @Pointcut("execution(* aimis.controller.AuthorityController.delete(*))")
    public void adminAuthorityDelete() {
    }

    @Pointcut("execution(* aimis.controller.AuthorityController.add(..))")
    public void adminAuthorityAdd() {
    }

    @Pointcut("execution(* aimis.controller.AuthorityController.edit(..))")
    public void adminAuthorityEdit() {
    }

    @Pointcut("execution(* aimis.controller.RoleController.delete(..))")
    public void adminRoleDelete() {
    }

    @Pointcut("execution(* aimis.controller.RoleController.add(..))")
    public void adminRoleAdd() {
    }

    @Pointcut("execution(* aimis.controller.RoleController.edit(..))")
    public void adminRoleEdit() {
    }

    @Before("adminUserEdit()")
    public void checkUserAdminEdit(JoinPoint joinPoint) {
        //获取调用方法的参数
        Object[] args = joinPoint.getArgs();
        UserForm userForm = (UserForm) args[1];
        BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this, this.getClass().getName());
        var user = userRepo.findById(userForm.getId()).get();
        // 修改管理员
        if (user.getLoginName().equals(adminName)) {
            // 想要修改管理员的登录名
            if (!userForm.getLoginName().equals(adminName)) {
                bindingResult.addError(new FieldError("userForm", "name", "admin不允许修改登录名"));
            }
            // 想要管理员的管理员角色取消掉
            Role admin = roleRepo.findByName(adminRole);
            if (!userForm.getRoleIds().contains(admin.getId())) {
                bindingResult.addError(new FieldError("userForm", "roleIds", "admin不允许取消管理员角色"));
            }
        }
    }

    @Before("adminUserDelete()")
    public void checkUserAdmin(JoinPoint joinPoint) {
        //获取调用方法的参数
        Object[] args = joinPoint.getArgs();
        UserForm userForm = (UserForm) args[0];
        BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this, this.getClass().getName());
        var user = userRepo.findById(userForm.getId()).get();
        if (user.getLoginName().equals(adminName)) {
            bindingResult.addError(new FieldError("userForm", "name", "admin不允许删除"));
            throw new MyBindException(bindingResult);
        }
    }

    @Before("adminDepartmentDelete()")
    public void checkDepartmentAdminDelete(JoinPoint joinPoint) {
        //获取调用方法的参数
        Object[] args = joinPoint.getArgs();
        DepartmentForm departmentForm = (DepartmentForm) args[0];
        BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this, this.getClass().getName());
        var department = departmentRepo.findById(departmentForm.getId()).get();
        if (department.getName().equals(adminDepartment)) {
            bindingResult.addError(new FieldError("departmentForm", "name", "adminDepartment(管理员部门)不允许删除"));
        }
    }

    @Before("adminDepartmentAdd()")
    public void checkDepartmentAdminAdd(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        DepartmentForm departmentForm = (DepartmentForm) args[0];
        BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this, this.getClass().getName());
        String departmentName = departmentForm.getName();
        if (departmentName != null && departmentName.equals(adminDepartment)) {
            bindingResult.addError(new FieldError("departmentForm", "name", "adminDepartment(管理员部门)不允许添加"));
        }
    }

    @Before("adminDepartmentEdit()")
    public void checkDepartmentAdminEdit(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        DepartmentForm departmentForm = (DepartmentForm) args[0];
        BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this, this.getClass().getName());
        Long departmentId = departmentForm.getId();
        var department = departmentRepo.findById(departmentId).get();
        // 阻止修改管理员部门名
        if (department.getName().equals(adminDepartment) && !departmentForm.getName().equals(department.getName())) {
            bindingResult.addError(new FieldError("departmentForm", "name", "adminDepartment(管理员部门)不允许修改"));
        }
    }

//    @Before("adminAuthorityDelete()")
//    public void checkAuthorityAdminDelete(JoinPoint joinPoint) {
//        //获取调用方法的参数
//        Object[] args = joinPoint.getArgs();
//        AuthorityForm authorityForm = (AuthorityForm) args[0];
//        BindingResult bindingResult = (BindingResult) args[1];
//        var authority = authorityRepo.findById(authorityForm.getId()).get();
//        if (authority != null && "用户权限管理".equals(authority.getName())) {
//            bindingResult.addError(new FieldError("authorityForm", "name", "adminAuthority(用户权限管理权限)不允许删除"));
//        }
//    }
//
//    @Before("adminAuthorityAdd()")
//    public void checkAuthorityAdminAdd(JoinPoint joinPoint) {
//        Object[] args = joinPoint.getArgs();
//        AuthorityForm authorityForm = (AuthorityForm) args[0];
//        BindingResult bindingResult = (BindingResult) args[1];
//        String authorityName = authorityForm.getName();
//        if (authorityName != null && "用户权限管理".equals(authorityName)) {
//            bindingResult.addError(new FieldError("authorityForm", "name", "adminAuthority(用户权限管理权限)不允许添加"));
//        }
//    }

//    @Before("adminAuthorityEdit()")
//    public void checkAuthorityAdminEdit(JoinPoint joinPoint) {
//        Object[] args = joinPoint.getArgs();
//        AuthorityForm authorityForm = (AuthorityForm) args[0];
//        BindingResult bindingResult = (BindingResult) args[1];
//        Long authorityId = authorityForm.getId();
//        var authority = authorityRepo.findById(authorityId).get();
//        if (authority != null && authority.getName().equals(adminAuthority)) {
//            bindingResult.addError(new FieldError("authorityForm", "name", "adminAuthority(用户权限管理权限)不允许修改"));
//        }
//        if (authority != null && authorityForm.getName().equals(adminAuthority)) {
//            bindingResult.addError(new FieldError("authorityForm", "name", "adminAuthority(用户权限管理权限)不允许重复存在"));
//        }
//    }

    @Before("adminRoleDelete()")
    public void checkRoleAdminDelete(JoinPoint joinPoint) {
        //获取调用方法的参数
        Object[] args = joinPoint.getArgs();
        RoleForm roleForm = (RoleForm) args[0];
        BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this, this.getClass().getName());
        var role = roleRepo.findById(roleForm.getId()).get();
        if (role.getName().equals(adminRole)) {
            bindingResult.addError(new FieldError("roleForm", "name", "adminRole(用户权限管理员角色)不允许删除"));
        }
    }

    @Before("adminRoleAdd()")
    public void checkRoleAdminAdd(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        RoleForm roleForm = (RoleForm) args[0];
        BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this, this.getClass().getName());
        String roleName = roleForm.getName();
        if (roleName != null && roleName.equals(adminRole)) {
            bindingResult.addError(new FieldError("roleName", "name", "adminRole(用户权限管理员角色)不允许添加"));
        }
    }

    @Before("adminRoleEdit()")
    public void checkRoleAdminEdit(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        RoleForm roleForm = (RoleForm) args[0];
        BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(this, this.getClass().getName());
        Long roleId = roleForm.getId();
        var role = roleRepo.findById(roleId).get();
        if (role.getName().equals(adminRole)) {
            bindingResult.addError(new FieldError("roleForm", "name", "adminRole(用户权限管理员角色)不允许修改"));
        }
        if (roleForm.getName().equals(adminRole)) {
            bindingResult.addError(new FieldError("roleForm", "name", "adminRole(用户权限管理员角色)不允许重复存在"));
        }
    }
}
